home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 245_01 / lca21.c < prev    next >
C/C++ Source or Header  |  1987-10-26  |  16KB  |  568 lines

  1.  
  2. /* (2,1) Linear Cellular Automaton    */
  3.  
  4. /* Reference:                */
  5. /*                    */
  6. /*    Kenneth E. Perry            */
  7. /*    Abstract Mathematical Art        */
  8. /*    BYTE                */
  9. /*    December, 1986            */
  10. /*    pages 181-192            */
  11.  
  12. /*    Copyright (C) 1987        */
  13. /*    Harold V. McIntosh        */
  14. /*    Gerardo Cisneros S.        */
  15.  
  16. /* G. Cisneros, 4.3.87                        */
  17. /* 10 April 1987 - modified for (4,2) [HVM]            */
  18. /* 26 April 1987 - Multiple menus [HVM]                */
  19. /* 28 April 1987 - back modified to (4,1) [HVM]            */
  20. /* 28 April 1987 - version for XVI Feria de Puebla [HVM]    */
  21. /* 14 May 1987 - modified for (3,1) and general rule [HVM]    */
  22. /* 20 May 1987 - modified for (2,1) and general rule [HVM]    */
  23. /* 21 May 1987 - Wolfram rule number [HVM]            */
  24.  
  25. # include <bdos.h>
  26.  
  27. # define COLGRAF     4  /* graph resolution            */
  28. # define T80X25      3  /* text resolution            */
  29. # define WHCYMAG     1  /* color quad for normal screen        */
  30. # define AL        320  /* array length (screen width)        */
  31. # define TS         4  /* distinct sums w/totalistic rule    */
  32. # define DS         8  /* number of distinct neighborhoods    */
  33. # define KK         2  /* number of states per cell        */
  34. # define NX          5    /* number of sample rules        */
  35.  
  36. char xrule[NX][KK][KK][KK];
  37.  
  38. char ixrule[NX][DS]=
  39.  
  40.     "00110011",    /* interfaces of 2 vel    */
  41.     "00110011",
  42.     "00111011",    /* mottled background    */
  43.     "00111001",    /* (0*102211200)* still */
  44.     "11111101"    /* 2 glider on 1 bkgrnd    */
  45.  
  46.     ;
  47.  
  48. char  xx[4], rule[DS+1], ascrule[KK][KK][KK];
  49. int   binrule[KK][KK][KK], arule[DS], arr1[AL], arr2[AL];
  50. char  trule[TS]="0000";
  51.  
  52. main()
  53. {
  54. int  i, j, i0, i1, i2;
  55. int  more = 'r';
  56. char a, b, c;
  57.  
  58. for (i=0; i<NX; i++) {                    /* copy to 3-index array */
  59. i0=0; i1=0; i2=0;
  60. for (j=0; j<DS; j++) {
  61.   xrule[i][i0][i1][i2]=ixrule[i][j];
  62.   i2++;
  63.   if (i2>KK-1) {i2=0; i1++;};
  64.   if (i1>KK-1) {i1=0; i0++;};
  65.   if (i0>KK-1) {i0=0; };
  66. };};
  67.  
  68.  
  69.     videopalette(WHCYMAG);                /* white/cyan/magenta */
  70.  
  71.     tuto();
  72.     while (!kbdst()) rand();                /* wait for keypress */
  73.     kbdin();                        /* ignore it */
  74.     videomode(T80X25);
  75.     videoscroll(3,0,5,71,0,3);                /* menu on blue background */
  76.     videoscroll(19,0,24,71,0,3);
  77.     xtoasc(rand()%NX);
  78.     rule[DS]=0;
  79.     ranlin();                        /* random initial array */
  80.  
  81.     while (more!='n') {                    /* execute multiple runs */
  82.     rmenu();
  83.     lmenu();
  84.     while (0<1) {                    /* set up one run */
  85.     c=kbdin();
  86.     if (c=='g') break;                    /* go draw graph */
  87.     if (c=='q') more='n';                /* quit for good */
  88.     if (more=='n') break;
  89.     switch (c) {
  90.     case '@':                    /* numbered tot rule */
  91.         nutoto(numin(0));
  92.         totoasc();
  93.         rmenu();
  94.         videocursor(0,4,0);
  95.         break;
  96.     case '$':                    /* dozen totalistics */
  97.         j=numin(0);
  98.         for (i=0; i<12; i++) {
  99.           nutoto(j+i);
  100.           totoasc();
  101.           ranlin();
  102.           evolve(rule);
  103.           };
  104.         videomode(T80X25);
  105.         rmenu();
  106.         lmenu();
  107.         break;
  108.     case 't':                    /* totalistic rule */
  109.         xblnk();
  110.         tmenu();
  111.         edtrule();
  112.         totoasc();
  113.         for (i0=0; i0<KK; i0++) {
  114.         for (i1=0; i1<KK; i1++) {
  115.         for (i2=0; i2<KK; i2++) {
  116.         ascrule[i0][i1][i2]=trule[i0+i1+i2];
  117.         };};};
  118.         videocursor(0,4,0);
  119.         rmenu();
  120.         xmenu(totonu(0));
  121.         break;
  122.         case 'r':                    /* edit rule */    
  123.         xblnk();
  124.         edrule();
  125.         videocursor(0,4,0);
  126.         rmenu();
  127.         break;
  128.         case 'l':                    /* edit cell string */
  129.         xblnk();
  130.         edline();
  131.         videocursor(0,3,0);
  132.         lmenu();
  133.         break;
  134.         case '#':                    /* read stored rule */
  135.         xmenu(NX);
  136.         xtoasc(lim(1,numin(0),NX)-1);
  137.         rmenu();
  138.             break;
  139.     case 'D':                    /* run through samples */
  140.         for (i=0; i<NX; i++) {
  141.           xmenu(i);
  142.           xtoasc(i);
  143.           ranlin();
  144.           evolve(rule);
  145.           };
  146.         videomode(T80X25);
  147.         rmenu();
  148.         break;
  149.         case 'u':                    /* sparse init arry */
  150.         xblnk();
  151.         for (i=0; i<AL; i++) arr1[i]=0;
  152.         arr1[AL/4]=1;
  153.             arr1[AL/2]=1;
  154.             arr1[(3*AL)/4]=1;
  155.             arr1[(3*AL)/4+2]=1;
  156.         lmenu();
  157.             break;
  158.     case 'w':                    /* Wolfram rulw # */
  159.         i=numin(0);
  160.         wmenu(i);
  161.         for (i0=0; i0<KK; i0++) {
  162.         for (i1=0; i1<KK; i1++) {
  163.         for (i2=0; i2<KK; i2++) {
  164.           ascrule[i0][i1][i2]='0'+i%2;
  165.           i/=2;
  166.         };};};
  167.         rmenu();
  168.         break;
  169.     case 'x':                    /* random rule */
  170.         xblnk();
  171.         for (i0=0; i0<KK; i0++) {
  172.         for (i1=0; i1<KK; i1++) {
  173.         for (i2=0; i2<KK; i2++) {
  174.           if ((KK*(KK*i0+i1)+i2)%4 == 0) i=rand();
  175.           ascrule[i0][i1][i2]='0'+i%2;
  176.           i/=2;
  177.         };};};
  178.         rmenu();
  179.         break;
  180.     case 'y':                    /* random line */
  181.         xblnk();
  182.         ranlin();
  183.             lmenu();
  184.         break;
  185.     case 'Y':                    /* symmetrize rule */
  186.         for (i0=0; i0<KK; i0++) {
  187.         for (i1=0; i1<KK; i1++) {
  188.         for (i2=0; i2<KK; i2++) {
  189.         ascrule[i2][i1][i0]=ascrule[i0][i1][i2];      
  190.         };};};
  191.         break;
  192.     case 'B':                    /* begin barrier */
  193.         a=kbdin();
  194.         b=kbdin();
  195.         ascrule[0][a-'0'][b-'0']=a;
  196.         ascrule[1][a-'0'][b-'0']=a;
  197.         ascrule[2][a-'0'][b-'0']=a;
  198.         rmenu();
  199.         break;
  200.     case 'E':                    /* end barrier */
  201.         a=kbdin();
  202.         b=kbdin();
  203.         ascrule[a-'0'][b-'0'][0]=b;
  204.         ascrule[a-'0'][b-'0'][1]=b;
  205.         ascrule[a-'0'][b-'0'][2]=b;
  206.         rmenu();
  207.         break;
  208.     case 'L':                    /* left glider link */
  209.         a=kbdin();
  210.         b=kbdin();
  211.         c=kbdin();
  212.         ascrule[a-'0'][b-'0'][c-'0']=c;
  213.         rmenu();
  214.         break;
  215.     case 'R':                    /* left glider link */
  216.         a=kbdin();
  217.         b=kbdin();
  218.         c=kbdin();
  219.         ascrule[a-'0'][b-'0'][c-'0']=a;
  220.         rmenu();
  221.         break;
  222.     case 'S':                    /* still life link */
  223.         a=kbdin();
  224.         b=kbdin();
  225.         c=kbdin();
  226.         ascrule[a-'0'][b-'0'][c-'0']=b;
  227.         rmenu();
  228.         break;
  229.     case '=':
  230.         for (i=1; i<8;  i++) {
  231.         for (j=0; j<40; j++) arr1[40*i+j]=arr1[j];};
  232.         lmenu();
  233.         break;
  234.     case '~':
  235.         for (i=1; i<16;  i++) {
  236.         for (j=0; j<20; j++) arr1[20*i+j]=arr1[j];};
  237.         lmenu();
  238.         break;
  239.         default: break;
  240.         };
  241.     };
  242.     if (more=='n') break;
  243.     do {
  244.     evolve(rule);
  245.     videocursor(0,0,0);
  246.     scrstr("More?");
  247.     videocursor(0,0,34);
  248.     scrstr("y/n/cr");
  249.     more=kbdin();
  250.     } while (more=='\015');
  251.     videomode(T80X25);                    /* reset the screen */
  252.     if (more=='n') break;
  253.     };
  254.   videomode(T80X25);}    
  255.  
  256. /* edit the rule */
  257. edrule() {
  258. char c;
  259. int  i, i0, i1, i2;
  260.  
  261. i=6; i0=0; i1=0, i2=0;
  262.     while (0<1) {
  263.         videocursor(0,3,i);
  264.         c = kbdin();
  265.         if (c == '\015') break;                /* carriage return exits */
  266.         switch (c) {
  267.         case '0':  case '1':                /* state */
  268.         ascrule[i0][i1][i2] = c;
  269.             i2++;
  270.         if (i2>KK-1) {i2=0; i1++;};
  271.         if (i1>KK-1) {i1=0; i0++;};
  272.         if (i0>KK-1) {i2=0; };
  273.             videocattr(0,c,3,1);
  274.             if (i<6+DS) i++;
  275.             break;
  276.         case ' ': case '\315':                /* space = advance */
  277.             i2++;
  278.         if (i2>KK-1) {i2=0; i1++;};
  279.         if (i1>KK-1) {i1=0; i0++;};
  280.         if (i0>KK-1) {i2=0; };
  281.             if (i<6+DS) i++;
  282.             break;
  283.         case '\010': case '\313':            /* backspace */
  284.         if (i2!=0) i2--; else {i2=KK-1;
  285.         if (i1!=0) i1--; else {i1=KK-1;
  286.         if (i0!=0) i0--; else {i0=KK-1;
  287.         };};};
  288.             if (i>6) i--;
  289.             break;
  290.     default: break;
  291.         };
  292.     };
  293. }
  294.  
  295. /* edit totalistic rule */
  296. edtrule() {char c; int  i;
  297.     i=0;
  298.     while (i<TS) {
  299.     c=trule[i];
  300.     videocursor(0,3,56+i);
  301.         videocattr(0,c,3,1);
  302.         c = kbdin();
  303.         if (c == '\015') break;
  304.         switch (c) {
  305.           case '0': case '1':                /* state */
  306.             trule[i]=c;
  307.             videocattr(0,c,5,1);
  308.         i++;
  309.             break;
  310.           case ' ': case '\315':            /* space = advance */
  311.         i++;
  312.             break;
  313.           case '\010': case '\313':            /* backspace */
  314.             if (i!=0) i--;
  315.         break;
  316.       default: break;
  317.           };
  318.     };
  319. }
  320.  
  321. /* edit the line */
  322. edline() {
  323. char c;
  324. int  i, j, k, ii, jj;
  325.  
  326.     videocursor(0,19,0);
  327.     scrstr("insert states using 0, 1,");
  328.     videocursor(0,